package org.apache.solr.ocean.replication;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;

import org.apache.solr.common.SolrException;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.ocean.OceanCore;
import org.apache.solr.ocean.OceanSearcher;
import org.apache.solr.ocean.core.TransactionSystem.Category;
import org.apache.solr.ocean.replication.LogFile2.Record;
import org.apache.solr.ocean.replication.LogFileManager.RecordIterator;
import org.apache.solr.ocean.replication.RawLogFile.StreamData;
import org.apache.solr.ocean.replication.RawLogFile.StreamRecord;
import org.apache.solr.ocean.util.Util;
import org.apache.solr.request.BinaryQueryResponseWriter;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.request.SolrQueryResponse;

public class TransactionResponseWriter implements BinaryQueryResponseWriter {
  public void write(OutputStream out, SolrQueryRequest request, SolrQueryResponse response) throws IOException {
    OceanSearcher oceanSearcher = (OceanSearcher) request.getSearcher();
    try {
      OceanCore oceanCore = oceanSearcher.getCore();
      Long id = new Long(request.getParams().get("id"));
      int num = request.getParams().getInt("num", 10);

      Category category = oceanCore.getCategory();
      Replication replication = category.getReplication();
      DataOutputStream dataOutput = new DataOutputStream(out);
      LogFileManager logFileManager = replication.getLogFileManager();
      RecordIterator recordIterator = logFileManager.getRecordIterator(id);
      int x = 0;
      List<Record> records = new ArrayList<Record>(num);
      while (recordIterator.hasNext() && x < num) {
        records.add(recordIterator.next());
      }
      dataOutput.writeInt(records.size());
      for (Record record : records) {
        dataOutput.writeLong(record.getId());
        dataOutput.writeUTF(record.getCategory());
        dataOutput.writeLong(record.getSchemaVersion());
        StreamRecord streamRecord = record.getStreamRecord();
        StreamData documentsStreamData = streamRecord.getDocuments();
        dataOutput.writeInt(documentsStreamData.getLength());
        byte[] buffer = new byte[1024*16];
        byte[] copyBuffer = new byte[1024*16];
        Util.copy(documentsStreamData.getInputStream(buffer), dataOutput, copyBuffer);
        StreamData otherStreamData = streamRecord.getOther();
        dataOutput.writeInt(otherStreamData.getLength());
        Util.copy(otherStreamData.getInputStream(buffer), dataOutput, copyBuffer);
      }
    } catch (Exception exception) {
      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Error return transaction", exception);
    }
  }

  public void init(NamedList args) {
    
  }

  public String getContentType(SolrQueryRequest request, SolrQueryResponse response) {
    return "application/octet-stream";
  }

  public void write(Writer writer, SolrQueryRequest request, SolrQueryResponse response) throws IOException {
  }
}
